import fs from 'fs'
import path from 'path'
import { LocalFile } from './sync'
import Oss, { NodeFile } from '@/tools/rawa-oss'
import { getDocByPath, del, upload as uploadFile, getDocById } from '@/api/doc'

const uid = 1000000

function genUuid (): string {
  return Date.now() + '-' + uid + '-' + String(Math.random()).slice(-4)
}

export function upload (file: LocalFile, baseDocId: number, localBasePath: string, pfn: (...args: any[]) => void): Promise<any> {
  const client = new Oss({
    endpoint: '',
    accessKeyId: '',
    accessKeySecret: '',
    stsToken: '',
    bucket: 'fs'
  })
  const p = `${genUuid()}/` + encodeURIComponent(file.name)
  return getFile(path.resolve(file.path, file.name), file.name).then(data => {
    const fn = (...args: any[]) => {
      pfn(client, ...args)
    }
    return client.multipartUpload(p, data, { progress: fn }).then(res => ({ f: data, res }))
  }).then(({ f, res }) => {
    const relativePath = (n(file.path) + '/').replace(n(localBasePath) + '/', '') + file.name
    const req = {
      parentId: baseDocId,
      name: relativePath,
      size: f.size,
      url: (res.res as any)?.requestUrls[0]
    }
    return uploadFile(req)
  })

  function n (p = '') {
    return p.replace(/\\/g, '/')
  }
}

function getFile (p: string, name: string): Promise<File | NodeFile> {
  return new Promise((resolve, reject) => {
    fs.stat(p, (err, stats) => {
      if (err) {
        reject(err)
        return
      }
      if (stats.size > 1024 * 1024 * 1) {
        resolve(new NodeFile(p, stats.size))
      } else {
        fs.readFile(p, (err, data) => {
          if (err) reject(err)
          else {
            const file = new File([data as any], name)
            return resolve(file)
          }
        })
      }
    })
  })
}

export function removeDoc (file: LocalFile, baseDocId: number, localBasePath: string): Promise<any> {
  return getDocById(baseDocId).then(root => {
    const p = root.path + '/' + (n(file.path) + '/').replace(n(localBasePath) + '/', '') + file.name
    return getDocByPath(p).then(doc => {
      return doc?.id ? del(doc?.id) : Promise.resolve(null)
    })
  }).catch(() => {
    return Promise.resolve(null)
  })

  function n (p = '') {
    return p.replace(/\\/g, '/')
  }
}
